package photorganizer.common.logging;

import java.lang.reflect.Array;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import photorganizer.common.util.Appender;


public class SimpleDumper implements Dumper {

	public void dump(StringBuilder stringBuilder, Object object) {
		if (object == null) {
			stringBuilder.append(object);
		}
		else if (object instanceof Appender) {
			((Appender) object).appendTo(stringBuilder);
		}
		else if (object.getClass().isArray()) {
			appendArray(stringBuilder, object);
		}
		else if (object instanceof Collection) {
			appendCollection(stringBuilder, (Collection<?>) object);
		}
		else if (object instanceof Map) {
			appendMap(stringBuilder, (Map<?, ?>) object);
		}
		else if (object instanceof Throwable) {
			appendThrowable(stringBuilder, (Throwable) object);
		}
		else if (object instanceof Proxy) {
			stringBuilder.append("Proxy");
		}
		else {
			stringBuilder.append(object.toString());
		}
	}

	protected void appendArray(StringBuilder stringBuilder, Object array) {
		stringBuilder.append('[');
		for (int i = 0; i < Array.getLength(array); i++) {
			if (i > 0) {
				stringBuilder.append(", ");
			}
			dump(stringBuilder, Array.get(array, i));
		}
		stringBuilder.append(']');
	}

	protected void appendCollection(StringBuilder stringBuilder, Collection<?> collection) {
		stringBuilder.append('[');
		Iterator<?> iterator = collection.iterator();
		while (iterator.hasNext()) {
			dump(stringBuilder, iterator.next());
			if (iterator.hasNext()) {
				stringBuilder.append(", ");
			}
		}
		stringBuilder.append(']');
	}

	protected void appendMap(StringBuilder stringBuilder, Map<?, ?> map) {
		stringBuilder.append('{');
		Iterator<?> iterator = map.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<?, ?> entry = (Map.Entry<?, ?>) iterator.next();
			dump(stringBuilder, entry.getKey());
			stringBuilder.append('=');
			dump(stringBuilder, entry.getValue());
			if (iterator.hasNext()) {
				stringBuilder.append(", ");
			}
		}
		stringBuilder.append('}');
	}

	protected void appendThrowable(StringBuilder stringBuilder, Throwable throwable) {
		for (StackTraceElement stackTraceElement : throwable.getStackTrace()) {
			stringBuilder.append(stackTraceElement.toString());
			stringBuilder.append(System.getProperty("line.separator"));
		}
	}

}
